//! # 死信队列系统演示
//!
//! 演示死信队列的核心功能，包括失败消息处理、重试机制、告警系统等

use rustcloud_bus::{
    dead_letter::{
        InMemoryDeadLetterQueue, DeadLetterConfig, DeadLetterQueue, RetryDelayStrategy,
        AlertThresholds, Alert, AlertLevel, AlertHandler,
    },
    message::Message,
    error::MessageBusResult,
};
use async_trait::async_trait;
use serde_json::json;
use std::collections::HashMap;
use std::sync::Arc;
use tokio::time::{sleep, Duration};
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};

/// 简单的告警处理器实现
struct ConsoleAlertHandler;

#[async_trait]
impl AlertHandler for ConsoleAlertHandler {
    async fn send_alert(&self, alert: Alert) -> MessageBusResult<()> {
        println!("🚨 [{:?}] {}: {}", alert.level, alert.title, alert.message);
        if !alert.data.is_empty() {
            println!("   数据: {:?}", alert.data);
        }
        Ok(())
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 初始化日志
    tracing_subscriber::registry()
        .with(tracing_subscriber::fmt::layer().with_target(false))
        .with(EnvFilter::from_default_env().add_directive("rustcloud_bus=debug".parse()?))
        .init();

    println!("🔄 死信队列系统演示开始\n");

    // 1. 创建死信队列配置
    println!("=== 1. 创建死信队列配置 ===");
    let config = DeadLetterConfig {
        enabled: true,
        max_retry_attempts: 3,
        retry_delay_strategy: RetryDelayStrategy::Exponential {
            initial_delay_secs: 5,
            max_delay_secs: 300,
            multiplier: 2.0,
        },
        max_dead_letter_messages: 1000,
        cleanup_interval_secs: 30,
        message_ttl_secs: 3600, // 1小时
        enable_alerts: true,
        alert_thresholds: AlertThresholds {
            dead_letter_count_threshold: 5,
            error_rate_threshold: 10.0, // 10%
            check_interval_secs: 10, // 10秒检查一次
        },
        auto_retry: true,
        retry_interval_secs: 15, // 15秒重试一次
    };

    println!("✅ 死信队列配置创建完成");
    println!("   • 最大重试次数: {}", config.max_retry_attempts);
    println!("   • 重试策略: 指数退避 (5s -> 300s, 倍数: 2.0)");
    println!("   • 最大死信消息数: {}", config.max_dead_letter_messages);

    // 2. 创建死信队列
    println!("\n=== 2. 创建死信队列 ===");
    let alert_handler = Arc::new(ConsoleAlertHandler);
    let dead_letter_queue = Arc::new(
        InMemoryDeadLetterQueue::new(config)
            .with_alert_handler(alert_handler)
    );

    // 启动死信队列后台任务
    dead_letter_queue.start().await?;
    println!("✅ 死信队列创建并启动成功");

    // 3. 模拟添加失败消息
    println!("\n=== 3. 添加失败消息到死信队列 ===");
    let failed_messages = vec![
        ("user.events.created", json!({"user_id": "user1", "email": "user1@example.com"}), "数据库连接超时"),
        ("order.events.placed", json!({"order_id": "order1", "amount": 99.99}), "支付服务不可用"),
        ("notification.events.sent", json!({"type": "email", "recipient": "test@example.com"}), "SMTP服务器错误"),
        ("inventory.events.updated", json!({"product_id": "prod1", "quantity": 100}), "库存服务异常"),
        ("analytics.events.tracked", json!({"event": "page_view", "user_id": "user2"}), "分析服务超时"),
    ];

    let mut dead_letter_ids = Vec::new();
    for (topic, payload, reason) in failed_messages {
        let message = Message::new(topic, payload);
        let mut error_details = HashMap::new();
        error_details.insert("service".to_string(), "demo-service".to_string());
        error_details.insert("error_code".to_string(), "TIMEOUT".to_string());
        
        let id = dead_letter_queue.add_dead_letter(
            message,
            reason.to_string(),
            Some(error_details),
        ).await?;
        
        dead_letter_ids.push(id.clone());
        println!("  💀 添加死信消息: {} -> {} ({})", topic, &id[..8], reason);
    }

    // 4. 查看死信队列统计
    println!("\n=== 4. 死信队列统计信息 ===");
    let stats = dead_letter_queue.get_stats().await?;
    println!("📊 统计信息:");
    println!("  • 总死信消息数: {}", stats.total_dead_letters);
    println!("  • 待重试消息数: {}", stats.pending_retry_count);
    println!("  • 错误率: {:.2}%", stats.error_rate);

    // 5. 获取重试候选消息
    println!("\n=== 5. 获取重试候选消息 ===");
    let retry_candidates = dead_letter_queue.get_retry_candidates(10).await?;
    println!("🔄 找到 {} 条可重试消息", retry_candidates.len());
    
    for (i, candidate) in retry_candidates.iter().take(3).enumerate() {
        println!("  {}. {} - {} (重试次数: {})", 
            i + 1, 
            candidate.source_topic,
            candidate.failure_reason,
            candidate.retry_count
        );
    }

    // 6. 模拟消息重试
    println!("\n=== 6. 模拟消息重试 ===");
    if !dead_letter_ids.is_empty() {
        let first_id = &dead_letter_ids[0];
        
        // 开始重试
        if dead_letter_queue.retry_message(first_id).await? {
            println!("  🔄 开始重试消息: {}", &first_id[..8]);
            
            // 模拟处理延迟
            sleep(Duration::from_millis(100)).await;
            
            // 模拟重试失败
            dead_letter_queue.mark_retry_failure(
                first_id,
                "网络连接失败".to_string()
            ).await?;
            println!("  ❌ 第一次重试失败: {}", &first_id[..8]);
            
            // 再次重试
            if dead_letter_queue.retry_message(first_id).await? {
                sleep(Duration::from_millis(100)).await;
                
                // 模拟重试成功
                dead_letter_queue.mark_retry_success(first_id).await?;
                println!("  ✅ 第二次重试成功: {}", &first_id[..8]);
            }
        }
    }

    // 7. 测试告警系统
    println!("\n=== 7. 测试告警系统 ===");
    println!("等待告警检查... (可能需要等待10秒)");
    
    // 等待一段时间让告警系统检查
    sleep(Duration::from_secs(12)).await;
    
    // 8. 查看单个死信消息详情
    println!("\n=== 8. 查看死信消息详情 ===");
    if dead_letter_ids.len() > 1 {
        let second_id = &dead_letter_ids[1];
        if let Some(dead_letter) = dead_letter_queue.get_dead_letter(second_id).await? {
            println!("📄 死信消息详情:");
            println!("  • ID: {}", dead_letter.id);
            println!("  • 原始主题: {}", dead_letter.source_topic);
            println!("  • 失败原因: {}", dead_letter.failure_reason);
            println!("  • 失败时间: {}", dead_letter.failed_at.format("%H:%M:%S"));
            println!("  • 重试次数: {}", dead_letter.retry_count);
            if let Some(next_retry) = dead_letter.next_retry_at {
                println!("  • 下次重试时间: {}", next_retry.format("%H:%M:%S"));
            }
            println!("  • 错误详情: {:?}", dead_letter.error_details);
        }
    }

    // 9. 清理过期消息
    println!("\n=== 9. 清理过期消息 ===");
    let cleaned = dead_letter_queue.cleanup_expired().await?;
    println!("🧹 清理了 {} 条过期消息", cleaned);

    // 10. 最终统计
    println!("\n=== 10. 最终统计信息 ===");
    let final_stats = dead_letter_queue.get_stats().await?;
    println!("📊 最终统计:");
    println!("  • 总死信消息数: {}", final_stats.total_dead_letters);
    println!("  • 待重试消息数: {}", final_stats.pending_retry_count);
    println!("  • 已重试消息数: {}", final_stats.retried_count);
    println!("  • 重试成功数: {}", final_stats.retry_success_count);
    println!("  • 重试失败数: {}", final_stats.retry_failure_count);
    println!("  • 永久失败数: {}", final_stats.permanent_failure_count);
    println!("  • 错误率: {:.2}%", final_stats.error_rate);

    println!("\n✅ 死信队列演示完成！");
    println!("\n💡 要查看详细日志，请运行:");
    println!("   RUST_LOG=debug cargo run --example dead_letter_demo");
    
    Ok(())
}